﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace Orders
{
    [Serializable]
    public class Order
    {
        public static int OrderQuantity = 0;//当前订单量
        public int OrderNum { set; get; }//订单编号
        public List<OrderItem> OrderItems = new List<OrderItem>();
        public Customer Customer { get; set; }
        public double TotalPrice {set;get;}

        public Order() { }
        public Order(Customer customer, List<OrderItem> orderItems)
        {
            OrderNum = OrderQuantity;
            Customer = customer;
            OrderItems = orderItems;
            OrderQuantity += 1;//订单编号直接由订单量决定，确保订单编号不重复
            foreach (OrderItem oi in orderItems)
                TotalPrice += oi.Price;
        }



        public override bool Equals(object obj)
        {
            var order = obj as Order;
            return order != null &&
                   EqualityComparer<List<OrderItem>>.Default.Equals(OrderItems, order.OrderItems);
        }



        public override string ToString()
        {
            String str1 = "OrderNum:" + OrderNum + " Customer:" + Customer + "\nOrderItems:\n";
            foreach (OrderItem orderItem in OrderItems)
            {
                str1 += orderItem.ToString();
            }
            str1 += "TotalPrice:" + TotalPrice;
            return str1;
        }

        public override int GetHashCode()
        {
            var hashCode = -996025175;
            hashCode = hashCode * -1521134295 + OrderNum.GetHashCode();
            hashCode = hashCode * -1521134295 + EqualityComparer<List<OrderItem>>.Default.GetHashCode(OrderItems);
            hashCode = hashCode * -1521134295 + EqualityComparer<Customer>.Default.GetHashCode(Customer);
            hashCode = hashCode * -1521134295 + TotalPrice.GetHashCode();
            return hashCode;
        }
    }

    public class Customer
    {
        public string Name { get; set; }
        public Customer() { }
        public Customer(string name)
        {
            Name = name;
        }
        public override string ToString()
        {
            return Name;
        }
    }

    public class Goods
    {
        public string Name;
        public double UnitPrice;
        public Goods() { }
        public Goods(string name, double price)
        {
            this.Name = name;
            this.UnitPrice = price;
        }
        public override string ToString()
        {
            return Name + " " + UnitPrice + "yuan/kg ";
        }
    }

    [Serializable]
    public class OrderItem
    {
        public Goods OrderGoods { get; set; }
        public int Quantity { get; set; }
        public double Price { get; set;}

        public OrderItem(Goods goods, int quantity)
        {
            this.OrderGoods = goods;
            this.Quantity = quantity;
            this.Price = this.OrderGoods.UnitPrice * quantity;
        }

        public OrderItem() { }
        public override string ToString()
        {
            return OrderGoods.ToString() + " " + Quantity + "kg ItemPrice:" + Price + "yuan\n";
        }

        public override bool Equals(object obj)
        {
            var item = obj as OrderItem;
            return item != null &&
                   EqualityComparer<Goods>.Default.Equals(OrderGoods, item.OrderGoods) &&
                   Quantity == item.Quantity &&
                   Price == item.Price;
        }

        public override int GetHashCode()
        {
            var hashCode = -1732923583;
            hashCode = hashCode * -1521134295 + EqualityComparer<Goods>.Default.GetHashCode(OrderGoods);
            hashCode = hashCode * -1521134295 + Quantity.GetHashCode();
            hashCode = hashCode * -1521134295 + Price.GetHashCode();
            return hashCode;
        }
    }

    public class OrderService
    {
        public List<Order> Orders = new List<Order>();

        public void AddOrder(Order order)
        {
            Orders.Add(order);
        }

        public void DeleteOrder(int num)
        {
            var orders = Orders
                           .Where(od => od.OrderNum == num);
            
                Orders.Remove(orders.ElementAt(0));
            
        }

        public void ReviseOrderByClient(int num, Customer client)
        {
            var orders = Orders
                           .Where(od => od.OrderNum == num);
            orders.ElementAt(0).Customer = client;
           
        }


        public Order InquiryOrderByNum(int num)
        {
            var orders = Orders
                           .Where(od => od.OrderNum == num);
            return orders.ElementAt(0); 
            //else throw new Exception("查找的订单不存在");
        }


        public Order InquiryOrderByClientName(string name)
        {
            var orders = Orders
                        .Where(order => order.Customer.Name == name)
                        .OrderBy(order => order.TotalPrice);
            if (orders == null)
                throw new Exception("没有这样的订单，查询失败");
            return orders.ToList()[0];
        }

        public Order InquiryOrderByGoodsName(string goodsName)
        {
            var ods = Orders.Where(
               order => order.OrderItems.Exists(OrderItem => OrderItem.OrderGoods.Name == goodsName));
            if (ods == null)
                throw new Exception("没有这样的订单，查询失败");
            return ods.ToList()[0];
        }

        public void SortOrders()
        {
            Orders.Sort((o1, o2) => o1.OrderNum - o2.OrderNum);
        }

        public void SortByTotalPrice()
        {
            Orders.Sort((o1, o2) => (int)(o1.TotalPrice - o2.TotalPrice));
        }

        public void Export(string path)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream(path, FileMode.Create))
            {
                xmlSerializer.Serialize(fs, Orders);
            }
        }

        public List<Order> Import(string path)
        {
            List<Order> ods = new List<Order>();
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
                ods = (List<Order>)xmlSerializer.Deserialize(fs);
                Console.WriteLine("\nDeserialized from s.xml");
                foreach (Order od in ods)
                    Console.WriteLine(od);
            }
            return ods;
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            Goods goods1 = new Goods("apple", 3);
            Goods goods2 = new Goods("pear", 5);
            Goods goods3 = new Goods("peach", 8);
        }
    }
}
